package com.gsbelarus.gedemin.lib.ui.viewpager;

import android.os.Bundle;
import android.support.v4.view.ViewPager;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;

import com.gsbelarus.gedemin.lib.R;
import com.gsbelarus.gedemin.lib.ui.ArgumentsHelper;
import com.gsbelarus.gedemin.lib.ui.dialog.DatePickerDialog;
import com.gsbelarus.gedemin.lib.ui.fragment.FragmentModel;
import com.gsbelarus.gedemin.lib.ui.interfaces.OnDateSet;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

/**
 * Фрагмент - обертка, служит для реализации слайдов влево-вправо
 * Создание и обработка нажатий на пункт меню Календарь в ActionBar происходит здесь
 */
abstract public class ViewPagerDateModel extends FragmentModel implements ViewPager.OnPageChangeListener {

    protected ViewPager mPager;
    protected ViewPagerDateAdapter mPagerAdapter;

    protected int currentPage;

    protected boolean isArguments;

    protected ArgumentsHelper argumentsHelper;
    protected DatePickerDialog datePickerDialog;

    protected List<Calendar> slidingDatesList;

    /**
     * @return id View для отрисовки в фрагменте
     */
    @Override
    public int getViewId() {
        return R.layout.view_pager;
    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        slidingDatesList = new ArrayList<Calendar>();

        /** Считываение параметров ViewPager: какой фрагмент открывать, какой диалог выбора даты показывать*/
        argumentsHelper = new ArgumentsHelper();
        argumentsHelper.readViewPagerInfo(getArguments());

        setReloadViewByChangingOrientation(false);
        /** читаем параметры, для последующей передачи их в отображаемый фрагмент */
        isArguments = argumentsHelper.readParams(getArguments());
    }

    /**
     * Вызывается при создании View или при смене ориентации экрана.
     * Может быть переопределен в классе наследнике
     *
     * @param rootView корневое View
     */
    @Override
    public void onCreateViewFragment(View rootView) {
        super.onCreateViewFragment(rootView);
        mPager = (ViewPager) rootView.findViewById(R.id.pager);
        mPager.setOnPageChangeListener(this);
    }

    @Override
    final public void readDataBase() {
        slidingDatesList = getDatesListInBackground();
    }

    /**
     * Выполняется в отдельном потоке
     *
     * @return массив с датами по которым будут доступны свайпы
     */
    abstract public List<Calendar> getDatesListInBackground();

    /**
     * Метод вызывается после чтения данных из БД или при смене ориентации экрана.
     * Может быть вызван до окончания выполнения потока для запроса данных из БД (если isReloadViewByChangingOrientation==true),
     * поэтому следует проверять данные на null.
     * Служит для инициализации View данными
     *
     * @param rootView корневое View
     */
    @Override
    public void initView(View rootView) {
        /** создаем календарь */
        initDatePicker();

        /** создаем адаптер для ViewPager */
        initAdapter();

        setHasOptionsMenu(true);

        /** устанавливаем дату*/
        setDate(isArguments);
    }

    private void initAdapter() {
        try {
            /** Создаем адаптер, в него передаем имя фрагмента для отображения и переменную по которой будем делать свайпы
             * (переменная может быть: день, месяц, год)
             */
            mPagerAdapter = new ViewPagerDateAdapter(getChildFragmentManager(),
                    Class.forName(argumentsHelper.className), argumentsHelper, slidingDatesList);
            mPager.setAdapter(mPagerAdapter);

        } catch (ClassNotFoundException e) {
            Log.d(getClass().getName(), e.getMessage());
        }
    }

    /**
     * Инициализация datePickerDialog-а датами из БД и назначение обработчика выбора даты
     */
    private void initDatePicker() {
        datePickerDialog = new DatePickerDialog(getActivity(), slidingDatesList, argumentsHelper.slidingDate);
        datePickerDialog.setOnDateSetListeners(new OnDateSet() {
            @Override
            public void updateDate(int day, int month, int year) {
                mPager.setCurrentItem(mPagerAdapter.getItemDate(day, month, year));
            }
        });
    }

    private void setDate(boolean isAgruments) {
        /** если есть параметры - ставим в календаре дату из параметров. */
        if (isAgruments)
            datePickerDialog.setDate(argumentsHelper.selectedDay, argumentsHelper.selectedMonth, argumentsHelper.selectedYear);
        else
            datePickerDialog.setDate(Calendar.getInstance());

        /** обновляем дату (вызовится метод onDateSet) */
        datePickerDialog.updateDate();
    }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.calendar_menu, menu);
        super.onCreateOptionsMenu(menu, inflater);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.calendar_item) {
            datePickerDialog.setDate(mPagerAdapter.getDate(currentPage));
            datePickerDialog.show();
        } else if (item.getItemId() == android.R.id.home)
            getActivity().finish();
        return super.onOptionsItemSelected(item);
    }

    public ViewPager getViewPager() {
        return mPager;
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageSelected(int position) {
        currentPage = position;
    }

    @Override
    public void onPageScrollStateChanged(int state) {
//        int first = (currentPage - 1 < 0) ? currentPage : currentPage - 1;
//        int last = (currentPage + 1 < mPagerAdapter.getCount()) ? currentPage + 1 : currentPage;
//        if (state == ViewPager.SCROLL_STATE_IDLE) {
//            for (int i = first; i <= last; i++)
//                ((FragmentModel) mPagerAdapter.instantiateItem(mPager, i)).setShowing(true);
//        } else
//            for (int i = first; i <= last; i++)
//                ((FragmentModel) mPagerAdapter.instantiateItem(mPager, i)).setShowing(false);
    }

    public DatePickerDialog getDatePickerDialog() {
        return datePickerDialog;
    }
}
